﻿namespace NMortgage.UI.Tests.ViewModels
{
    using Microsoft.Practices.Unity;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    using Moq;

    using NMortgage.UI.Events;
    using NMortgage.UI.Model;
    using NMortgage.UI.ViewModels;

    [TestClass]
    public class InterestParameterViewModelTest : TestBase
    {
        #region Fields

        private InterestParameter _rate;

        #endregion Fields

        #region Properties

        private InterestParameterViewModel Subject
        {
            get; set;
        }

        #endregion Properties

        #region Methods

        [TestMethod]
        public void Available_Types_Not_Empty()
        {
            Subject = new InterestParameterViewModel(Helper.EventAggregator.Object);
            var actual = Subject.AvailableTypes;
            Assert.IsNotNull(actual);
        }

        [TestMethod]
        public void Cancel_will_publish_CancelEvent()
        {
            Subject.Cancel();
            Helper.EventAggregator.Verify(x => x.Publish(It.Is<CancelEvent>(c=>c.Source.GetType() == typeof(InterestParameterViewModel))));
        }

        [TestMethod]
        public void Cant_have_invalid_Rate()
        {
            bool actual;
            bool expected = false;

            InterestParameter validationTarget = new InterestParameter(DistributionType.FixedRate);
            validationTarget.Months = 0;

            validationTarget.Years = 0;

            Subject.Rate = validationTarget;

            actual = Subject.IsValid;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Can_have_null_Rate()
        {
            bool actual;
            bool expected = true;

            Subject.Rate = null;

            actual = Subject.IsValid;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Finish_Will_Publish()
        {
            Subject.Finish();

            Helper.EventAggregator.Verify(x => x.Publish(It.Is<ProfileItemAdded>(p => p.Item == _rate)));
        }

        [TestInitialize]
        public void Initialize()
        {
            _rate = new InterestParameter(DistributionType.FixedRate);
            Subject = Helper.Resolve<InterestParameterViewModel>(new ParameterOverride("parameter", _rate));
        }

        [TestMethod]
        public void Must_have_valid_Rate()
        {
            bool actual;
            bool expected = true;
            InterestParameter validationTarget = new InterestParameter(DistributionType.FixedRate);
            validationTarget.Months = 1;

            Subject.Rate = validationTarget;

            actual = Subject.IsValid;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void RateView_IsBaseRateVMType()
        {
            Subject = new InterestParameterViewModel(Helper.EventAggregator.Object);
            var actual = Subject.RateView;
            Assert.IsInstanceOfType(actual, typeof(ARateViewModel));
        }

        [TestMethod]
        public void RateView_Not_Null()
        {
            Subject = new InterestParameterViewModel(Helper.EventAggregator.Object);
            var actual = Subject.RateView;
            Assert.IsNotNull(actual);
        }

        [TestMethod]
        public void Type_BetaDistribution_returns_BetaRateInstance()
        {
            Subject.RateDistributionType = DistributionType.BetaDistribution;
            IDistribution actual = Subject.Rate.Distribution;
            Assert.IsInstanceOfType(actual, typeof(BetaDistribution));
        }

        [TestMethod]
        public void Type_FixedRate_returns_FixedRateInstance()
        {
            Subject.RateDistributionType = DistributionType.FixedRate;
            IDistribution actual = Subject.Rate.Distribution;
            Assert.IsInstanceOfType(actual, typeof(FixedRate));
        }

        [TestMethod]
        public void Type_NormalDistribution_returns_NormalRateInstance()
        {
            Subject.RateDistributionType = DistributionType.NormalDistribution;
            IDistribution actual = Subject.Rate.Distribution;
            Assert.IsInstanceOfType(actual, typeof(NormalDistribution));
        }

        [TestMethod]
        public void Type_Not_Null()
        {
            Subject = new InterestParameterViewModel(Helper.EventAggregator.Object);
            var actual = Subject.RateDistributionType;
            Assert.IsNotNull(actual);
        }

        [TestMethod]
        public void Type_UniformDist_returns_UniformRateInstance()
        {
            Subject.RateDistributionType = DistributionType.UniformDistribution;
            IDistribution actual = Subject.Rate.Distribution;
            Assert.IsInstanceOfType(actual, typeof(UniformDistribution));
        }

        [TestMethod]
        public void Use_FixedRate_As_Default()
        {
            Subject = new InterestParameterViewModel(Helper.EventAggregator.Object);
            Assert.IsInstanceOfType(Subject.Rate.Distribution, typeof(FixedRate));
        }

        #endregion Methods
    }
}